"""
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    created by lane.chang on '07/09/2022'
    comment: 工程全局使用的变量以及函数等
"""
import os
import logging
import aioredis
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
from sqlalchemy.orm import sessionmaker
from pydantic import Field
from contextvars import ContextVar

from config import Config
from laner.pydantic import BaseModel
from project.core.log import Log, LogConfig


# ====================日志对象部分====================
logging.basicConfig(level=Config.LOGGER_LEVEL)  # 项目日志级别

# 普通日志
logger = Log(logger_name=str(os.getpid()), log_config=LogConfig(**Config.LOGGER), display_console=Config.DISPLAY_CONSOLE)

# MQTT日志
logger_mqtt = Log(logger_name=str(os.getpid()) + "_mqtt", log_config=LogConfig(**Config.LOGGER_MQTT), display_console=Config.DISPLAY_CONSOLE)

# ====================数据库连接池部分====================
async_engine = create_async_engine(**Config.DB_OPTIONS)
async_session = sessionmaker(bind=async_engine, class_=AsyncSession, expire_on_commit=False)

# 创建 ContextVar，用于存储当前上下文的会话
session_context: ContextVar[AsyncSession] = ContextVar("session_context")


# 使用 ContextVar 实现 async_scoped_session 的效果
class AsyncScopedSession:

    def __init__(self, session_factory):
        self.session_factory = session_factory
        self.token = None

    async def __aenter__(self):
        session = self.session_factory()
        self.token = session_context.set(session)
        return session

    async def __aexit__(self, exc_type, exc_val, exc_tb):
        session = session_context.get()
        await session.close()
        session_context.reset(self.token)


# ====================redis连接部分====================
# 创建异步 Redis 连接池
async def get_redis_pool():
    """
    :return:
    """
    pool = await aioredis.from_url(**Config.REDIS_OPTIONS)

    return pool


# 使用 ContextVar 实现 async_scoped_session 的效果
class AsyncRedis:

    def __init__(self):
        self.pool = None

    async def __aenter__(self):
        self.pool = await get_redis_pool()
        return self.pool.client()

    async def __aexit__(self, exc_type, exc_val, exc_tb):
        await self.pool.close()


# ====================sqlalchemy所有表model====================
tables = {}  # 初始加载赋值 key: 表名  value: 表model

# ====================计数器====================


class Global:

    _count = 0

    @classmethod
    def count(cls) -> int:
        """ 全局计数器
        :return:
        """
        cls._count += 1
        return cls._count


# ====================Api 接口参数====================
class ApiParam(BaseModel):
    """
    """
    path: str = Field('', title='api url路径')
    body_params: list = Field([], title='body参数')
    query_params: list = Field([], title='query参数')
    path_params: list = Field([], title='路径参数')


api_param_map: dict[str, ApiParam] = {}

